import React, { Component } from 'react';
import JSZip from './jszip.min.js';
import X2JS from './xml2json.min.js';
/**
 * 定义一个React类组件Var2JavaEntity，它接收一个Urule变量库的XML格式字符串，并将其【转换】为Java实体类，以及【下载】功能
 */
export default class Var2JavaEntity extends Component {
    constructor(props) {
        super(props);
        this.state = {
            javaEntityMap: new Map(),
            uruleVar: '',
            javaEntity: ''
        };
    }
    /**
     * urule4的变量xml转换成java实体类
     * @returns 
     */
    uruleVarToJavaEntity = () => {
        const { uruleVar, javaEntityMap } = this.state;
        if (!uruleVar) {
            alert("请输入Urule变量库文件源码！");
            return;
        }
        this.setState({ javaEntity: '' }); // 先清空转换后的结果...

        try {
            const data = this.loadXMLDoc(uruleVar);
            const categoryList = data["variable-library"]["category"];
            let entityContent = '';

            for (let i = 0; i < categoryList.length; i++) {
                const category = categoryList[i];
                const clazz = category["_clazz"];
                const _package = clazz.substring(0, clazz.lastIndexOf('.'));
                let entity = `package ${_package};\n\n`;
                entity += "import com.bstek.urule.model.Label;\n";
                entity += this.dealVarType(category) + "\n";
                const entityName = clazz.split('.').pop();
                entity += `public class ${entityName} {\n\n`;

                const varList = category["var"];
                for (let j = 0; j < varList.length; j++) {
                    const v = varList[j];
                    const varLabel = v["_label"];
                    const varType = v["_type"];
                    const varName = v["_name"];
                    if (varName.indexOf(".") === -1) {
                        entity += `    @Label("${varLabel}")\n`;
                        entity += `    private ${varType} ${varName};\n`;
                    }
                }

                entity += "\n";

                for (let j = 0; j < varList.length; j++) {
                    const v = varList[j];
                    //const varLabel = v["_label"];
                    const varType = v["_type"];
                    const varName = v["_name"];
                    if (varName.indexOf(".") === -1) {
                        entity += `    public ${varType} get${varName[0].toUpperCase()}${varName.substr(1)}() { return ${varName}; }\n\n`;
                        entity += `    public void set${varName[0].toUpperCase()}${varName.substr(1)}(${varType} ${varName}) { this.${varName} = ${varName}; }\n\n`;
                    }
                }

                entity += "}\n";
                entityContent += entity + "\n=============================================================================================================================================\n";
                javaEntityMap.set(entityName, entity);
            }

            this.setState({ javaEntity: entityContent });
        } catch (error) {
            alert("Urule变量库文件源码格式有误！\n" + error.message);
            console.error(error);
        }
    };
    /**
     * 数据类型映射与转换
     * @param {大类} category 
     * @returns 
     */
    dealVarType = (category) => {
        const varTypeSet = new Set();
        let importStr = '';
        const varList = category["var"];

        for (let i = 0; i < varList.length; i++) {
            const varType = varList[i]["_type"];
            const varName = varList[i]["_name"];
            if (varName.indexOf(".") === -1) {
                if (varType === "Char") {
                    varList[i]["_type"] = "char";
                }
                varTypeSet.add(varType);
            }
        }

        for (const varType of varTypeSet) {
            if (varType === "List") {
                importStr += "import java.util.List;\n";
            } else if (varType === "Set") {
                importStr += "import java.util.Set;\n";
            } else if (varType === "Map") {
                importStr += "import java.util.Map;\n";
            } else if (varType === "Date") {
                importStr += "import java.util.Date;\n";
            } else if (varType === "BigDecimal") {
                importStr += "import java.math.BigDecimal;\n";
            }
        }

        return importStr;
    };
    /**
     * 字符串转换成json
     * @param {下载的数据} data 
     * @returns 
     */
    loadXMLDoc = (data) => {
        const x2js = new X2JS();
        const json = x2js.xml_str2json(data);
        return json;
    };
    /**
     * 下载文件
     */
    downloadJavaEntity = () => {
        const { javaEntityMap } = this.state;
        if (javaEntityMap.size === 0) {
            alert("未发现转化完成的java实体类");
        } else if (window.confirm("确定下载转换完成的java实体类吗？")) {
            const zip = new JSZip();
            javaEntityMap.forEach((val, key) => {
                zip.file(`${key}.java`, val);
            });
            zip.generateAsync({ type: "blob" }).then((content) => {
                const link = document.createElement('a');
                link.download = "javaEntity.zip";
                link.href = URL.createObjectURL(content);
                link.click();
                URL.revokeObjectURL(link.href);
            });
        }
    };

    render() {
        const { uruleVar, javaEntity } = this.state;
        return (
            <div>
                <div>Urule变量库文件源码：</div>
                <textarea
                    id="UruleVar"
                    rows="10"
                    cols="30"
                    style={{ width: '1450px', height: '175px' }}
                    value={uruleVar}
                    onChange={(e) => this.setState({ uruleVar: e.target.value })}
                />
                <div>
                    <input
                        id="convertBt"
                        type="button"
                        value="转换"
                        onClick={this.uruleVarToJavaEntity}
                    />
                    <input
                        id="download"
                        type="button"
                        value="下载Java实体类"
                        onClick={this.downloadJavaEntity}
                    />
                </div>
                <div>Java实体类预览：</div>
                <textarea
                    id="JavaEntity"
                    rows="10"
                    cols="30"
                    style={{ width: '1450px', height: '350px' }}
                    readOnly
                    value={javaEntity}
                />
            </div>
        );
    }
}